#!/usr/local/bin/sbcl --script

(defun primep (n)
  (cond ((= n 1) nil)
	((< n 4) t)
	((zerop (mod n 2)) nil)
	((< n 9) t) ;;; already excluded 4,6,8
	((zerop (mod n 3)) nil)
	(t (do ((r (floor (sqrt n))) (f 5 (+ f 6)))
	       ((or (zerop (mod n f)) (zerop (mod n (+ f 2))) (> f r))
		(if (> f r)
		    t
		    nil))
	     ))))

(defun prime-list (end &optional (start 2))
  (loop for i from start to end
       when (primep i)
       collect i))

;;;;;;;;;;; guess but how to proof it?
;;; as: (start + end) * count / 2 = limit*2, so the possible longest consecutive sum will be found in range[0,count]
;;; and when sum is 1000000, the sequence is 727, the prime is 5507, the range is [0, 727]
;;; Found this by accidently...could be truth???
;;;;;;;;;;;
(defun euler-50 (&optional (limit 1000))
  (let* ((original-prime-list (prime-list limit))
	 (max-count-limit (loop for i from 2 to (/ limit 2)
				when (> (* i (+ 2 (nth i original-prime-list))) (* 4 limit))
				return i))
	 (a-prime-list (subseq original-prime-list 0 max-count-limit))
	 (primes-count (length a-prime-list))
	 (init-sum 0)
	 (raw-result (loop for i from 0 to primes-count
	      append (loop for j from i to (1- primes-count)
		    and sum = init-sum then (+ (nth j a-prime-list) sum)
		    when (and (primep sum) (<= sum limit))
	            collect (list sum (- j i) i j)))))
	 (reduce #'(lambda (x y) (if (>= (second x) (second y)) x y)) raw-result)))
;    (list raw-result)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; test
;(print (time (euler-50 1000)))

(defparameter limit 1000000)
(let* ((original-prime-list (prime-list limit))
       (max-count-limit (loop for i from 2 to (/ limit 2)
			  when (> (* i (+ 2 (nth i original-prime-list))) (* 4 limit))
			   return  i))
       (a-prime-list (subseq original-prime-list 0 max-count-limit)))
  (print max-count-limit)
  (print (nth max-count-limit original-prime-list))
  (print (reduce '+ a-prime-list)))
